[新機能]dbtのsnapshotsがyamlファイル上で定義できるようになり、snapshots出力先のスキーマ・データベースを環境別に分けることもできるようになりました
さがらです。
2024年10月のdbt Cloudのリリースノートにおいて、下記の記述内容のアップデートがありました。現在、dbt CloudではVersionlessの場合に利用ができ、dbt-coreではもうまもなく一般提供となるv1.9から利用することができます。
Enhancement: In dbt Cloud Versionless, snapshots defined in SQL files can now use config defined in schema.yml YAML files. This update resolves the previous limitation that required snapshot properties to be defined exclusively in dbt_project.yml and/or a config() block within the SQL file. This will also be released in dbt Core 1.9.
これまでのdbtのsnapshotsは、SQLファイル上でsnapshotのconfigを設定することで利用できるものでした。(以下、以前私が書いたブログです。snapshotsがどういったものか、という説明もこちらのブログで書いております。)
それが、今回のアップデートで、snapshotsの設定がyamlファイルで定義するだけで出来るようになりました!公式ドキュメントも更新されています。
この内容を試してみたので、本記事でまとめてみます。
検証内容
status_table
というテーブルを用意しておき、このテーブルに対するsnapshotsを作っていきます。
snapshots対象のテーブルをref関数/source関数で参照できるようにする
yamlでsnapshotsの定義をする場合は、対象のテーブルをref関数/source関数で参照できるようにしておく必要があります。
今回は生データであるテーブルに対してsnapshotsを設定するため、事前にsourcesを下記のように定義しておきました。
version: 2
sources:
- name: test_data
database: sagara_rawdata_db
schema: test_data
tables:
- name: status_table
yamlでのsnapshotの設定
リポジトリのルート階層のsnapshots
ディレクトリに任意の名称のyamlファイルを作成し、下記のように記述します。
以前の.sqlファイルのconfigとして書く時と比べて、異なる点が2点あります。
schema
とdatabase
で出力先のスキーマを設定できるようになりました。- これにより
generate_schema_name
マクロやgenerate_database_name
マクロに沿った挙動でスキーマとデータベースが設定されるため、これまでのsnapshotでは難しかった「snapshotsの開発環境・本番環境の分離」が出来るようになります!(従来のsnapshotsでは、開発・本番で出力先を分けることが出来ませんでした。) - 参考情報ですが、
generate_schema_name
マクロをカスタムしたい場合はこちらの記事も参考になると思います。
- これにより
dbt_valid_to_current
というパラメータで、現在有効なレコードを示したい時に、どの日時を入れるかを指定できるようになりました。(デフォルトはNULLです。)
他のパラメータについては公式Docをご覧ください。
snapshots:
- name: orders_snapshot
relation: source('test_data', 'status_table')
config:
schema: snapshots
database: sagara_rawdata_db
unique_key: id
strategy: timestamp
updated_at: updated_at
dbt_valid_to_current: "to_date('9999-12-31')"
1回目のdbt snapshotの実行
これまでの設定を行った上で、dbt snapshot
を一度実行してみます。
すると、今回はdbt CloudのIDEA(開発環境)で実行したので、デフォルトのgenerate_schema_nameマクロの挙動に従い、dbt_ssagara_snapshots
というスキーマが作られ、その中にorders_snapshot
というsnapshotsのテーブルが作られました。
snapshots特有のカラムも追加されています。
対象テーブルをUPDATEした後に2回目のdbt snapshotの実行
次に、snapshotsの対象テーブルにUPDATE文をかけた後で、どのようにsnapshotsが変化するかを確認してみます。
まず、対象のテーブルに対して以下のUPDATE文を実行します。
update status_table
set
status = 'completed',
updated_at = current_timestamp()
where id = 3;
この後で、もう一度dbt snapshot
コマンドを実行します。
この後でsnapshotsで作られたテーブルを見るとSCD Type-2の形でレコードが更新されていることがわかります。
最後に
dbt snapshotsをyamlファイル上で定義できるようになったので、試した内容をまとめてみました。
私も試している最中で知ったのですが、記事中でも書いた通りgenerate_schema_name
マクロやgenerate_database_name
マクロに沿った挙動でスキーマとデータベースが設定されるため、これまでのsnapshotsでは難しかった「snapshotsの開発環境・本番環境の分離」が出来るようになったことがとても嬉しいですね!
逆にデメリットを言うと、開発環境で不用意にdbt build
などを行うとsnapshotsが開発者のスキーマごとに作られてしまうので、この点だけご注意ください。